#include "Paddle.hpp"
#include "Game.hpp"

#include "Ball.hpp"
#include "Extra.hpp"

Paddle::Paddle(Game* g):
	MoveableEntity(g)
{
}


//helper function
bool isBall(Entity* ent)
{
	if(dynamic_cast<Ball*>(ent))
		return true;
	return false;
}

void Paddle::onInput(InputStruct Input)
{

	//to avoid to big mouse jumps...
	/*if(Input.relMouseX>+3)
		Input.relMouseX=+3;
	if(Input.relMouseX<-3)
		Input.relMouseX=-3;*/

	velocity=Vector3f(Input.relMouseX, 0, 0);
	manager->MoveEntity(this, 1);

	//release a new ball
	//only if we have balls left, and there are non in the game atm
	if(Input.leftMButton && game->getBalls()>0 && manager->FindEntities(isBall).size() < game->getMaxCurrentBalls())
	{
		Ball* ball = new Ball(game, Vector3f(0, 1, 0.0f).normalize()*5);
		ball->setPosition(position+Vector3f(0.0f, 1.0f, 0.0f));
		if(manager->addEntity(ball))
			game->decrementBalls();
		game->PlaySound("launch");
	}
}

void Paddle::onTouch(Entity* Toucher)
{
	Ball* ball=dynamic_cast<Ball*>(Toucher);
	if(ball)
	{
		//change the direction according to the touch point:
		Vector3f direction=ball->getVelocity();
		float speed=direction.length();
		direction.normalize();

		//we asume, that the paddle is moving along the a-axis
		direction.x+=(ball->getPosition().x-position.x)
						/(cm.max.x-cm.min.x)*3;//normalize it to the paddle length
		//(the position difference is quite little, because the ball just hit the paddle...

		//we changed one axis, so we need to normalize again:
		direction.normalize();

		//the ball must never be too flat
		float minAngle=0.3f;
		if(direction.y<minAngle &&direction.y>=0.0f)
		{
			direction.y=minAngle;
			direction.normalize();
		}
		if(direction.y>-minAngle &&direction.y<=0.0f)
		{
			direction.y=-minAngle;
			direction.normalize();
		}

		//speed the ball a bit up
		ball->setVelocity(direction*(speed+0.333f));

		game->PlaySound("paddle");
	}

	if(dynamic_cast<Extra*>(Toucher))
	{
		auto extra_ball = uniform_int_distribution<>(0,1);

		manager->markToRemove(Toucher);
		
		if(extra_ball(game->rnd))
		{
			game->extraBall();
			game->PlaySound("extra_ball");
		}
		else
		{
			game->incrementScore(8);
			game->PlaySound("extra_score");
		}
	}
}
